package com.devenv.entity;

import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import jakarta.persistence.*;
import java.time.LocalDateTime;

/**
 * 系统配置实体类
 * <p>
 * 用于存储系统级别的配置信息，支持多种数据类型的配置值
 * </p>
 * 
 * @author DevEnv OpenSource Team
 * @version 1.0.0
 * @since 1.0.0
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "system_config", indexes = {
    @Index(name = "idx_config_key", columnList = "configKey"),
    @Index(name = "idx_config_type", columnList = "configType"),
    @Index(name = "idx_config_public", columnList = "isPublic")
})
public class SystemConfig {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "config_key", nullable = false, unique = true, length = 100)
    private String configKey;

    @Column(name = "config_value", nullable = false, columnDefinition = "TEXT")
    private String configValue;

    @Enumerated(EnumType.STRING)
    @Column(name = "config_type", nullable = false, length = 20)
    private ConfigType configType = ConfigType.STRING;

    @Column(name = "description", length = 500)
    private String description;

    @Column(name = "is_public", nullable = false)
    private Boolean isPublic = false;

    @Column(name = "is_system", nullable = false)
    private Boolean isSystem = false;

    @Column(name = "sort_order")
    private Integer sortOrder = 0;

    @Column(name = "config_group", length = 50)
    private String configGroup;

    @CreationTimestamp
    @Column(name = "created_at")
    private LocalDateTime createdAt;

    @UpdateTimestamp
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;

    /**
     * 配置类型枚举
     */
    public enum ConfigType {
        STRING("字符串"),
        NUMBER("数字"),
        BOOLEAN("布尔值"),
        JSON("JSON对象"),
        TEXT("长文本"),
        URL("网址"),
        EMAIL("邮箱"),
        PASSWORD("密码");

        private final String description;

        ConfigType(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    /**
     * 获取字符串值
     */
    public String getStringValue() {
        return configValue;
    }

    /**
     * 获取数字值
     */
    public Long getNumberValue() {
        try {
            return Long.parseLong(configValue);
        } catch (NumberFormatException e) {
            return null;
        }
    }

    /**
     * 获取双精度数字值
     */
    public Double getDoubleValue() {
        try {
            return Double.parseDouble(configValue);
        } catch (NumberFormatException e) {
            return null;
        }
    }

    /**
     * 获取布尔值
     */
    public Boolean getBooleanValue() {
        if (configValue == null) {
            return null;
        }
        return Boolean.parseBoolean(configValue);
    }

    /**
     * 设置字符串值
     */
    public void setStringValue(String value) {
        this.configValue = value;
        this.configType = ConfigType.STRING;
    }

    /**
     * 设置数字值
     */
    public void setNumberValue(Long value) {
        this.configValue = value != null ? value.toString() : null;
        this.configType = ConfigType.NUMBER;
    }

    /**
     * 设置双精度数字值
     */
    public void setDoubleValue(Double value) {
        this.configValue = value != null ? value.toString() : null;
        this.configType = ConfigType.NUMBER;
    }

    /**
     * 设置布尔值
     */
    public void setBooleanValue(Boolean value) {
        this.configValue = value != null ? value.toString() : null;
        this.configType = ConfigType.BOOLEAN;
    }

    /**
     * 检查配置是否可以被普通用户访问
     */
    public boolean isAccessibleToPublic() {
        return Boolean.TRUE.equals(isPublic);
    }

    /**
     * 检查配置是否为系统级配置（不可删除）
     */
    public boolean isSystemConfig() {
        return Boolean.TRUE.equals(isSystem);
    }

    /**
     * 验证配置值是否符合指定类型
     */
    public boolean isValidValue() {
        if (configValue == null) {
            return true; // null值在大多数情况下是允许的
        }

        try {
            switch (configType) {
                case NUMBER:
                    Double.parseDouble(configValue);
                    return true;
                case BOOLEAN:
                    // 允许的布尔值: true, false, 1, 0, yes, no, on, off
                    String lowerValue = configValue.toLowerCase();
                    return lowerValue.equals("true") || lowerValue.equals("false") ||
                           lowerValue.equals("1") || lowerValue.equals("0") ||
                           lowerValue.equals("yes") || lowerValue.equals("no") ||
                           lowerValue.equals("on") || lowerValue.equals("off");
                case URL:
                    return configValue.matches("^https?://.*");
                case EMAIL:
                    return configValue.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");
                case JSON:
                    // 这里可以添加JSON格式验证
                    return configValue.startsWith("{") || configValue.startsWith("[");
                default:
                    return true; // STRING, TEXT, PASSWORD 类型总是有效的
            }
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 配置分组枚举
     */
    public enum ConfigGroup {
        SYSTEM("系统配置"),
        DATABASE("数据库配置"),
        CACHE("缓存配置"),
        SECURITY("安全配置"),
        EMAIL("邮件配置"),
        STORAGE("存储配置"),
        INTEGRATION("集成配置"),
        UI("界面配置"),
        FEATURE("功能配置"),
        OTHER("其他配置");

        private final String description;

        ConfigGroup(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }
}
